import xtend from 'xtend';

import { getSblxBySbzlx } from '../../../../mapUtils/SblxUtil';
import { getStyle } from '../../../../mapUtils/StyleListUtil';
import { projectWebMercatorToLngLat } from '../../../../mapUtils/CoordinateUtil';
import { randomUUID } from '../../../../mapUtils/RandomUtil';
import CONST from '../../../../constant/Common';
import Ipms from './Ipms';
import SliceUtil from '../../utils/SliceUtil';

/**
 * 电网点设备修改接口
 * @interface
 * @implements {Ipms}
 */
class IpmsPoint extends Ipms {
  constructor(_tool) {
    super(_tool);
    this.relateLineLayerId = 'gl-draw-custom-relate-line';
    this.type = null;
    this.option = null;
    this.isEditing = false;
    // 切割的缓冲距离：单位米
    this.sliceThreshold = 0.2;
  }

  /**
   * 新增电网点设备
   * @override
   * @param {Object} option 默认参数
   * @param {Array} snapList 捕捉图形
   */
  draw(option, snapList) {
    this.type = 'add';
    this.option = option;
    this.sliceThreshold = this.option.sliceThreshold || 0.2;
    this.properties.drawtype = this.drawtype;
    this.properties.sourceType = 'Marker';
    this.properties.iconImage = this.option.icon || this.configIcon(option);
    return super.draw('snap_point', snapList);
  }

  /**
   * 编辑电网点设备
   * @override
   * @param {Object} option 默认参数
   * @param {Array} snapList 捕捉图形
   */
  edit(option, snapList) {
    this.type = 'edit';
    this.option = option;
    this.properties.drawtype = this.drawtype;
    this.properties.sourceType = 'Marker';
    this.properties.iconImage = this.option.icon || this.configIcon(option);
    let feature = turf.feature(this.option.geometry, Object.assign(this.option, this.properties));
    feature.id = randomUUID();
    this.setDrawStyle();
    //   不处理关联的线
    // this.initRelateLineLayer();
    // this.getRelateLines(feature);
    this.getTool('EditTool').setEvents({
      onDragmove: () => {
        this.isEditing = true;
        // 不处理关联的线
        // this.relateLines.forEach((line) => {
        //     line.geometry.coordinates[line.properties.changeIndex] = [
        //         e.lngLat.lng,
        //         e.lngLat.lat,
        //     ];
        // });
        // this.getMap()
        //     .getSource(this.relateLineLayerId)
        //     .setData(turf.featureCollection(this.relateLines));
      },
      onSelectionchange: (e) => {
        if (e.features.length === 0) {
          if (this.isEditing) {
            this.drawEnd();
          } else {
            this.stop();
            if(this.events.onReset) {
              this.events.onReset();
            }
          }
        }
      },
      onKeyDown: (e) => {
        if (e.keyCode === 8 || e.keyCode === 46) {
          if (this.getTool('EditTool').getMode() === 'simple_select') {
            if(this.events.onDelete) {
              this.events.onDelete(this.option);
            }
          }
        }
      }
    });
    return super.edit('simple_select', feature, snapList);
  }

  /**
   * 根据设备属性加载图标式样
   * @param {Object} option 设备属性
   */
  configIcon(option) {
    let style = getStyle(option, {
      zoom: this.getTool('BaseMapTool').getZoom()
    });
    if (style && style.iconImage) {
      this.defaultIcon = style.iconImage;
    }
    return this.defaultIcon;
  }

  /**
   * 获取起点设备
   */
  getStartDevice() {
    if (this.snaps) {
      var properties = this.snaps.properties;
      return xtend({}, properties, {
        sblx: getSblxBySbzlx(properties.sbzlx)
      });
    }
    return null;
  }

  /**
   * 获取终点设备
   */
  getEndDevice() {
    // 点设备：起点和终点一致
    return this.getStartDevice();
  }

  /**
   * 停止
   * @override
   */
  stop() {
    if(this.getMap().getSource(this.relateLineLayerId)) {
      this.getMap()
        .getSource(this.relateLineLayerId)
        .setData(turf.featureCollection([]));
    }
    super.stop();
  }

  /**
   * 修改完成
   * @override
   * @param {*} e 修改后的数据
   * @ignore
   */
  async updateHandle(e) {
    super.updateHandle(e);
    if (this.type === 'add') {
      console.log('update_handle', e.features[0]);
      let snap = e.features[0].properties.snaps;
      let ruleJudgeResult = await this._ruleJudgePoint(0, snap);
      this.verificationCallback(ruleJudgeResult);
      if (!ruleJudgeResult.success) {
        this.restart();
      } else {
        this.drawEnd();
      }
    }
  }

  /**
   * 设备样式设置
   * @ignore
   */
  setDrawStyle() {
    var layerConfig = {
      id: 'gl-draw-customize-' + this.drawtype,
      type: 'symbol',
      filter: ['all', ['==', '$type', 'Point'], ['==', 'symbol_drawtype', this.drawtype]],
      layout: {
        'icon-image': '{symbol_iconImage}',
        'icon-size': ['get', 'symbol_iconSize'],
        'icon-allow-overlap': true,
        'icon-ignore-placement': true,
        'icon-anchor': 'center',
        'text-field': '{label}',
        'text-size': 12,
        'text-font': ['Microsoft YaHei Regular'],
        'text-offset': [0, 1],
        'text-max-width': 8,
        'text-ignore-placement': false,
        'text-allow-overlap': false,
        'text-optional': true
      },
      paint: {
        'text-color': ['get', 'color'],
        'text-halo-color': '#FFFFFF',
        'text-halo-width': 1.33333
      }
    };
    this._setupLayerConfig(layerConfig, 'hot');
    this._setupLayerConfig(layerConfig, 'cold');
  }

  /**
   * 初始化关联线图层
   */
  initRelateLineLayer() {
    // 初始化数据源
    if(!this.getMap().getSource(this.relateLineLayerId)) {
      this.getMap().addSource(this.relateLineLayerId, {
        type: 'geojson',
        data: {
          type: 'FeatureCollection',
          features: []
        }
      });
    }
    // 初始化图层
    if(!this.getMap().getLayer(this.relateLineLayerId)) {
      this.getMap().addLayer({
        id: this.relateLineLayerId,
        type: 'line',
        source: this.relateLineLayerId,
        layout: {
          'line-cap': 'round',
          'line-join': 'round'
        },
        paint: {
          'line-color': '#fbb03b',
          'line-dasharray': [0.2, 2],
          'line-width': 2
        }
      });
    }
  }

  /**
   * 查询点设备关联的线路
   * @param {Object} point 点设备
   */
  getRelateLines(point) {
    this.getApi()
      .PwghGhsjTxfw.sbjh.post_sbjh_queryXlByD({
        params: {
          schema: this.option.schema,
          ghrw: this.option.ghrw || '',
          ghfa: this.option.ghfa || '',
          ghnf: this.option.ghnf || '',
          ghxm: this.option.ghxm || '',
          fxlx: this.option.fxlx || 2,
          oid: this.option.oid,
          sbzlx: this.option.sbzlx,
          verRule: CONST.verRule
        }
      })
      .then((res) => {
        let features = [];
        res.datas.forEach((line) => {
          let geometry = JSON.parse(line.shapejson);
          if (geometry && geometry.coordinates) {
            geometry.coordinates = projectWebMercatorToLngLat(geometry.coordinates);
            let feature = turf.feature(geometry, line);
            feature.properties.changeIndex = this.getNearestPointIndex(feature, point);
            features.push(feature);
          }
        });
        this.relateLines = features;
        this.getMap()
          .getSource(this.relateLineLayerId)
          .setData(turf.featureCollection(this.relateLines));
      });
  }

  /**
   * 获取线路距离点设备最近的一个端点的下标
   * @param {feature} line 线路
   * @param {feature} point 点设备
   */
  getNearestPointIndex(line, point) {
    let lineCoord = line.geometry.coordinates;
    let distance0 = turf.distance(turf.point(lineCoord[0]), point);
    let distance1 = turf.distance(turf.point(lineCoord[lineCoord.length - 1]), point);
    return distance0 < distance1 ? 0 : lineCoord.length - 1;
  }

  /**
   * 获取编辑后的图形数据
   */
  getChangedShapeList() {
    let list = [
      {
        oid: this.option.oid,
        sbzlx: this.option.sbzlx,
        blockid: this.option.blockid,
        versionid: this.option.versionid,
        shape: this.getGeometryWkt(this.geometry)
      }
    ];
    // this.relateLines.forEach((line) => {
    //     list.push({
    //         oid: line.properties.oid,
    //         sbzlx: line.properties.sbzlx,
    //         blockid: line.properties.blockid,
    //         versionid: line.properties.versionid,
    //         shape: this.getGeometryWkt(line.geometry),
    //     });
    // });
    return list;
  }


  getSplitInfo() {

    // 起点设备，就是被分割的线
    var startDevice = this.getStartDevice();
    if(!startDevice){
        return {
            
        }
    }
    var coordinates = projectWebMercatorToLngLat(startDevice.geometry.coordinates);
    console.log('before', coordinates);
    if(coordinates[0] === this.geometry.coordinates) {
      // 捕捉的是起点
      return {
        segment1: null,
        segment2: this.getGeometryWkt(turf.line(coordinates).geometry)
      };
    }else if(coordinates[coordinates.length - 1] === this.geometry.coordinates) {
      // 捕捉的是终点
      return {
        segment1: this.getGeometryWkt(turf.line(coordinates).geometry),
        segment2: null
      };
    }


    var line = window.turf.lineString(coordinates);
    var start = turf.point(coordinates[0]);
    var snapPoint = turf.point(this.geometry.coordinates);
    var stop = turf.point(coordinates[coordinates.length - 1]);
    console.log('snapPoint', snapPoint);
    var geometry1 = turf.lineSlice(start, snapPoint, line).geometry;
    var geometry2 = turf.lineSlice(snapPoint, stop, line).geometry;
    geometry1.coordinates[geometry1.coordinates.length - 1] = this.geometry.coordinates;
    geometry2.coordinates[0] = this.geometry.coordinates;
    // 修正端点精度
    console.log('geometry1', geometry1);
    console.log('geometry2', geometry2);
    var segment1 = this.getGeometryWkt(geometry1);
    var segment2 = this.getGeometryWkt(geometry2);
    return {
      segment1,
      segment2
    };
  }

  getSliceInfo() {

    // 起点设备，就是被切割的线
    var startDevice = this.getStartDevice();
    // 没有起点设备时，返回空对象
    if(!startDevice)
        return {
            start:null, finish:null, between:null, rotate:null
        }
    var coordinates = projectWebMercatorToLngLat(startDevice.geometry.coordinates);
    var line = turf.lineString(coordinates);


    var polygon = turf.circle(turf.point(this.geometry.coordinates), this.sliceThreshold / 1000, {
      steps: 100
    });
    return SliceUtil.slice(line, polygon);
  }
}

export default IpmsPoint;
